package com.cjkj.applet.service.impl;

import com.cjkj.applet.domain.TEquipmentUsageRecords;
import com.cjkj.applet.domain.THospitalEquipment;
import com.cjkj.applet.domain.TPatVisit;
import com.cjkj.applet.domain.dto.HospitalEquipmentDto;
import com.cjkj.applet.domain.vo.MonitorPadDataVo;
import com.cjkj.applet.domain.vo.SmartBraceletDataVo;
import com.cjkj.applet.mapper.TEquipmentUsageRecordsMapper;
import com.cjkj.applet.mapper.THospitalEquipmentMapper;
import com.cjkj.applet.mapper.TPatVisitMapper;
import com.cjkj.applet.service.EquipmentService;
import com.cjkj.common.core.constant.EquipmentConstants;
import com.cjkj.common.core.constant.HttpStatus;
import com.cjkj.common.core.constant.SecurityConstants;
import com.cjkj.common.core.domain.PatVisitIntervalData;
import com.cjkj.common.core.domain.R;
import com.cjkj.common.core.exception.ServiceException;
import com.cjkj.common.core.utils.DateUtils;
import com.cjkj.common.core.utils.StringUtils;
import com.cjkj.common.core.utils.bean.BeanUtils;
import com.cjkj.common.core.web.domain.AjaxResult;
import com.cjkj.common.security.utils.SecurityUtils;
import com.cjkj.system.api.RemoteTJ01DataService;
import com.cjkj.system.api.RemoteTJ02DataService;
import com.cjkj.system.api.RemoteTJ03DataService;
import com.cjkj.system.api.domain.APIMonitorPadData;
import com.cjkj.system.api.domain.APISmartBraceletData;
import com.cjkj.system.api.domain.APITJ03RealTimeData;
import com.cjkj.system.api.domain.request.*;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class EquipmentServiceImpl implements EquipmentService {
    @Resource
    private RemoteTJ01DataService remoteTJ01DataService;
    @Resource
    private RemoteTJ02DataService remoteTJ02DataService;
    @Resource
    private RemoteTJ03DataService remoteTJ03DataService;
    @Resource
    private TEquipmentUsageRecordsMapper equipmentUsageRecordsMapper;
    @Resource
    private TPatVisitMapper patVisitMapper;
    @Resource
    private THospitalEquipmentMapper hospitalEquipmentMapper;

    @Override
    public MonitorPadDataVo getMonitorPadRealTimeData(Long visitNo) {

        MonitorPadDataVo monitorPadDataVo = new MonitorPadDataVo();

        // 1、查询患者使用的设备
        TEquipmentUsageRecords usageRecord = equipmentUsageRecordsMapper.listRecordOneByVisitNo(visitNo, EquipmentConstants.EQUIPMENT_TYPE_MONITOR_PAD_TYPE, EquipmentConstants.EQUIPMENT_USE_FLAG_INUSE);
        if(usageRecord == null) {
            return monitorPadDataVo;
        }

        // 2、查询患者使用该设备期间的最新一条监测数据
        String equipmentNo = usageRecord.getEquipmentNo();
        PatientEquipmentRTDReq req = new PatientEquipmentRTDReq(equipmentNo, usageRecord.getEquipmentType(),
                usageRecord.getStartTime(), null);
        Date endTime = fmtEndTime(visitNo);
        req.setEndTime(usageRecord.getEndTime() == null || usageRecord.getEndTime().after(endTime) ? endTime : usageRecord.getEndTime());

        R<APIMonitorPadData> monitorPadDataResult = remoteTJ01DataService.getLastMonitorPadDataInUse(req, SecurityConstants.INNER);
        if(StringUtils.isNotNull(monitorPadDataResult) && R.FAIL != monitorPadDataResult.getCode()
                && StringUtils.isNotNull(monitorPadDataResult.getData())){
            BeanUtils.copyProperties(monitorPadDataResult.getData(),monitorPadDataVo);

            // 3、查询设备状态
            THospitalEquipment equipment = hospitalEquipmentMapper.selectByEquipmentId(SecurityUtils.getAppUserId(), usageRecord.getEquipmentId());
            monitorPadDataVo.setEquipmentStatus(equipment != null ? equipment.getOnlineStatus() : "1");
        }

        // 判断在线状态（暂用）
        // 如果监测时间间隔当前时间超过2分钟，判定为离线
        if(monitorPadDataVo.getAcquisitionTime() != null) {
            Date acquisitionTime = monitorPadDataVo.getAcquisitionTime();
            Date now = new Date();
            long millis = now.getTime() - acquisitionTime.getTime();
            if(millis < 1000 * 120) {
                // 在线
                monitorPadDataVo.setEquipmentStatus("0");
            } else {
                monitorPadDataVo.setEquipmentStatus("1");
            }
        }

        return monitorPadDataVo;
    }

    @Override
    public AjaxResult getMonitorHistoryData(EquipmentHistoryReq req) {

        // 1、查询患者使用的设备
        TEquipmentUsageRecords usageRecord = equipmentUsageRecordsMapper.listRecordOneByVisitNo(req.getVisitNo(), EquipmentConstants.EQUIPMENT_TYPE_MONITOR_PAD_TYPE, EquipmentConstants.EQUIPMENT_USE_FLAG_INUSE);
        if(usageRecord == null) {
            return AjaxResult.success(Collections.emptyList());
        }
        // 组装参数
        req.setEquipmentNo(usageRecord.getEquipmentNo());
        req.setStartTime(usageRecord.getStartTime());
        Date endTime = fmtEndTime(req.getVisitNo());
        req.setEndTime(usageRecord.getEndTime() == null || usageRecord.getEndTime().after(endTime) ? endTime : usageRecord.getEndTime());

        // 2、查询设备数据记录
        EquipmentHDAReq equipmentHDAReq = new EquipmentHDAReq();
        BeanUtils.copyProperties(req, equipmentHDAReq);
        R<?> result = remoteTJ01DataService.appListEquipmentHDA(equipmentHDAReq);
        if(StringUtils.isNull(result) || R.FAIL == result.getCode()){
            throw new ServiceException("获取设备历史数据失败！");
        }
        return AjaxResult.success(result.getData());
    }

    private Date fmtEndTime(Long visitNo){
        TPatVisit patVisit = patVisitMapper.selectTPatVisitByVisitNo(visitNo);
        PatVisitIntervalData intervalTime = DateUtils.getIntervalTime(patVisit.getVisitTime(), patVisit.getRentalDays(), patVisit.getOutTime(), patVisit.getDataType());
        return intervalTime.getOutTime();
    }

    @Override
    public SmartBraceletDataVo getBraceletRealTimeData(Long visitNo) {
        TPatVisit patInfo = patVisitMapper.selectTPatVisitByVisitNo(visitNo);
        if(patInfo == null) {
            return null;
        }

        List<TEquipmentUsageRecords> tEquipmentUsageRecords = equipmentUsageRecordsMapper.listRecordsByVisitNo(patInfo.getVisitNo(), patInfo.getDataType());
        // 按开始使用时间倒序排序
        List<TEquipmentUsageRecords> recordsSort = tEquipmentUsageRecords.stream()
                .sorted(Comparator.comparing(TEquipmentUsageRecords::getStartTime).reversed())
                .collect(Collectors.toList());

        PatVisitIntervalData intervalTime = DateUtils.getIntervalTime(patInfo.getVisitTime(), patInfo.getRentalDays(), null, patInfo.getDataType());
        SmartBraceletDataVo braceletDataVo = new SmartBraceletDataVo();
        for (TEquipmentUsageRecords records : recordsSort) {
            PatientEquipmentRTDReq req = new PatientEquipmentRTDReq();
            req.setEquipmentNo(records.getEquipmentNo());
            req.setStartTime(records.getStartTime());
            req.setEndTime(records.getEndTime() == null || records.getEndTime().after(intervalTime.getOutTime()) ? intervalTime.getOutTime() : records.getEndTime());
            R<APISmartBraceletData> result = remoteTJ02DataService.getLastBraceletDataInUse(req, SecurityConstants.INNER);
            if (result.getCode() == HttpStatus.SUCCESS && result.getData() != null) {
                APISmartBraceletData data = result.getData();
                if(data.getAcquisitionTime() != null) {
                    BeanUtils.copyBeanProp(braceletDataVo, data);

                    // 查询设备状态
                    THospitalEquipment equipment = hospitalEquipmentMapper.selectByEquipmentId(SecurityUtils.getAppUserId(), records.getEquipmentId());
                    braceletDataVo.setEquipmentStatus(equipment != null ? equipment.getOnlineStatus() : "1");

                    break;
                }
            }
        }

        // 判断在线状态（暂用）
        // 如果监测时间间隔当前时间超过10分钟，判定为离线
        if(braceletDataVo.getAcquisitionTime() != null) {
            Date acquisitionTime = braceletDataVo.getAcquisitionTime();
            Date now = new Date();
            long millis = now.getTime() - acquisitionTime.getTime();
            if(millis < 1000 * 600) {
                // 在线
                braceletDataVo.setEquipmentStatus("0");
            } else {
                braceletDataVo.setEquipmentStatus("1");
            }
        }

        return braceletDataVo;
    }

    @Override
    public AjaxResult getBraceletHistoryData(EquipmentHistoryReq req) {
        Long visitNo = req.getVisitNo();

        // 1、查询患者就诊信息
        TPatVisit patVisit = patVisitMapper.selectTPatVisitByVisitNo(visitNo);
        if(patVisit == null) {
            AjaxResult.error("患者就诊信息不存在！");
        }
        // 获取患者预计出院时间
        PatVisitIntervalData intervalTime = DateUtils.getIntervalTime(patVisit.getVisitTime(), patVisit.getRentalDays(), null, patVisit.getDataType());

        List<BraceletHistoryDataReqEquipmentInfo> equipmentInfos = new ArrayList<>();
        // 2、查询患者使用的设备
        List<TEquipmentUsageRecords> tEquipmentUsageRecords = equipmentUsageRecordsMapper.listRecordsByVisitNo(visitNo, EquipmentConstants.EQUIPMENT_TYPE_SMART_BRACELET_TYPE);

        for (TEquipmentUsageRecords record : tEquipmentUsageRecords) {
            BraceletHistoryDataReqEquipmentInfo info = new BraceletHistoryDataReqEquipmentInfo();
            info.setEquipmentNo(record.getEquipmentNo());
            info.setStartTime(record.getStartTime());
            info.setEndTime(record.getEndTime() == null || record.getEndTime().after(intervalTime.getOutTime()) ? intervalTime.getOutTime() : record.getEndTime());

            equipmentInfos.add(info);
        }

        // 3、组装参数，请求数据
        BraceletHistoryDataReq braceletHistoryDataReq = new BraceletHistoryDataReq();
        braceletHistoryDataReq.setEquipmentInfos(equipmentInfos);
        braceletHistoryDataReq.setPageNum(req.getPageNum());
        braceletHistoryDataReq.setPageSize(req.getPageSize());
        R<Object> result = remoteTJ02DataService.reqBraceletHistoryData(braceletHistoryDataReq, SecurityConstants.INNER);
        if(StringUtils.isNull(result) || R.FAIL == result.getCode()){
            throw new ServiceException("获取设备历史数据失败！");
        }
        return AjaxResult.success(result.getData());
    }

    @Override
    public SmartBraceletDataVo getBraceletBatteryData(String equipmentNo) {

        HospitalEquipmentDto query = new HospitalEquipmentDto();
        query.setEquipmentNo(equipmentNo);
        THospitalEquipment equipment = hospitalEquipmentMapper.select(query);
        if(equipment == null) {
            throw new ServiceException("设备编号不存在！");
        }

        LatestDatasReq req = new LatestDatasReq(equipmentNo, equipment.getCreateTime(), new Date(), 1);
        R<List<APISmartBraceletData>> result = remoteTJ02DataService.getLatestDatas(req, SecurityConstants.INNER);
        List<APISmartBraceletData> dataList = result.getData();
        if (result.getCode() == HttpStatus.SUCCESS && ! dataList.isEmpty()) {
            APISmartBraceletData apiSmartBraceletData = dataList.get(0);

            SmartBraceletDataVo vo = new SmartBraceletDataVo();
            vo.setEquipmentNo(equipmentNo);
            vo.setBatteryPercentage(apiSmartBraceletData.getBatteryPercentage());
            vo.setAcquisitionTime(apiSmartBraceletData.getAcquisitionTime());
            return vo;
        }
        return null;
    }

    @Override
    public APITJ03RealTimeData getEBRealTimeData(Long visitNo) {
        // 查询使用记录
        List<TEquipmentUsageRecords> tEquipmentUsageRecords = equipmentUsageRecordsMapper.listRecordsByVisitNo(visitNo, EquipmentConstants.EQUIPMENT_TYPE_EB_TYPE);
        if (tEquipmentUsageRecords.isEmpty()) {
            return new APITJ03RealTimeData();
        }
        List<RecordsReq> reqs = new ArrayList<>();
        for (TEquipmentUsageRecords usageRecord : tEquipmentUsageRecords) {
            RecordsReq req = new RecordsReq();
            req.setEquipmentNo(usageRecord.getEquipmentNo());
            req.setStartTime(usageRecord.getStartTime());
            req.setEndTime(usageRecord.getEndTime() == null ? new Date() : usageRecord.getEndTime());
            reqs.add(req);
        }

        // 查询最新一条监测数据
        R<APITJ03RealTimeData> apitj03RealTimeDataR = remoteTJ03DataService.getTj03RealTimeData(reqs, SecurityConstants.INNER);
        if (apitj03RealTimeDataR.getCode() == HttpStatus.SUCCESS) {
            return apitj03RealTimeDataR.getData();
        }
        return new APITJ03RealTimeData();
    }

    @Override
    public AjaxResult getEBHistoryData(EquipmentHistoryReq req) {
        return AjaxResult.success();
    }

    @Override
    public APITJ03RealTimeData getTj03BatteryData(String equipmentNo) {
        R<APITJ03RealTimeData> latestBatteryData = remoteTJ03DataService.getLatestBatteryData(equipmentNo, SecurityConstants.INNER);
        if (latestBatteryData.getCode() == HttpStatus.SUCCESS) {
            return latestBatteryData.getData();
        }
        return null;
    }

    @Override
    public APITJ03RealTimeData getDebugData(String equipmentNo) {
        R<APITJ03RealTimeData> latestData = remoteTJ03DataService.getTJ03LatestData(equipmentNo, SecurityConstants.INNER);
        if (latestData.getCode() == HttpStatus.SUCCESS) {
            return latestData.getData();
        }
        return null;
    }
}